package com.qhs.framework.utils;

import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import com.google.zxing.*;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;

import static com.google.zxing.client.j2se.MatrixToImageWriter.toBufferedImage;

/**
 * Created by xinchao on 2017/6/21 0021.
 */
public class BarCode {
    private static final String FORMAT="PNG";

    /**
     * 生成条形码<br>
     * <b>注意</b>条形码的宽度不能等于图片的宽度，否则解析不出来,如果解析不出来，请加大offset的值
     * @param contents 内容
     * @param dest 条形码图片地址
     * @param width 宽度
     * @param height 高度
     * @param offset 偏移量
     * @throws WriterException
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void encode(String contents,String dest,int width,int height,int offset) throws WriterException, FileNotFoundException, IOException{
        contents=new String(contents.getBytes("UTF-8"),"ISO-8859-1");
        BitMatrix matrix=new MultiFormatWriter().encode(contents, BarcodeFormat.CODE_128, width-offset, height);
        MatrixToImageWriter.writeToStream(matrix, FORMAT, new FileOutputStream(new File(dest)));
    }

    public static void writeToStream(String content, OutputStream stream, int width,int height,int offset) throws WriterException, IOException {
        BitMatrix matrix=new MultiFormatWriter().encode(content, BarcodeFormat.CODE_128, width-offset, height);
        MatrixToImageWriter.writeToStream(matrix, "png", stream);
    }


    /**
     * 解析条形码
     * @param dest 要解码的图片地址
     * @return String 条形码内容
     * @throws IOException
     * @throws NotFoundException
     */
    public static String decode(String dest) throws IOException, NotFoundException{
        BufferedImage image=ImageIO.read(new File(dest));
        LuminanceSource source=new BufferedImageLuminanceSource(image);
        BinaryBitmap imageBinaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
        Result result = new MultiFormatReader().decode(imageBinaryBitmap,null);
        return result.getText();
    }

    private static final String CODE = "utf-8";
    private static final int BLACK = 0xff000000;
    private static final int WHITE = 0xFFFFFFFF;

    public static BufferedImage getBarcode(String str, Integer width,
                                           Integer height)
    {

        if (width == null || width < 200)
        {
            width = 200;
        }

        if (height == null || height < 50)
        {
            height = 50;
        }

        try
        {
            // 文字编码
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, CODE);

            BitMatrix bitMatrix = new MultiFormatWriter().encode(str,
                    BarcodeFormat.CODE_128, width, height, hints);

            return toBufferedImage(bitMatrix);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 转换成图片
     *
     * @author wuhongbo
     * @param matrix
     * @return
     */
    private static BufferedImage toBufferedImage(BitMatrix matrix)
    {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
            }
        }
        return image;
    }


    /**
     * @param args
     * @throws Exception
     */
/*    public static void main(String[] args) throws Exception {

     //   BarCode.encode("12312312342", "d:\\Target.PNG", 150, 50,10);
      //  System.out.println("解析结果:"+BarCode.decode("d:\\Target.PNG"));

        ByteArrayOutputStream ous = new ByteArrayOutputStream();
        BarCode.writeToStream("12312312342",ous,150,50,10);
        byte[] ss = ous.toByteArray();
        DocFlavor dof = DocFlavor.INPUT_STREAM.PNG;
        PrintUtil.initStream(ss,dof);
    }*/
}
